import { cloneDeep } from 'lodash'

/**
 * 遍历树
 * @param tree
 * @param cb {function}
 * @param children {string} 子节点字段名
 * @param mode {'DFS' | 'BFS'} 遍历模式
 */
export function treeForEach(
  tree = [],
  cb = () => {},
  childrenField ='children',
  mode = 'DFS') {
  if (!Array.isArray(tree)) {
    throw new TypeError('tree is not array')
  }
  if (typeof childrenField !== 'string') {
    throw new TypeError('childrenField is not string')
  }
  if (childrenField === '') {
    throw new Error('childrenField is not a valid string')
  }
  // 深度优先遍历 DFS
  function DFS(treeData) {
    for (const item of treeData) {
      cb(item)
      if (Array.isArray(item[childrenField])) {
        DFS(item[childrenField])
      }
    }
  }
  // 广度优先遍历 BFS
  function BFS(treeData) {
    const queen = cloneDeep(treeData)
    while (queen.length > 0) {
      const item = queen.shift()
      cb(item)
      if (Array.isArray(item[childrenField])) {
        queen.push(...item[childrenField])
      }
    }
  }
  if (mode === 'BFS') {
    BFS(tree)
  } else {
    DFS(tree)
  }
}

/**
 * 树转数组
 * @param tree
 * @param childrenField
 * @param mode {'DFS' | 'BFS'} 遍历模式
 */
export function treeToArr(
  tree = [],
  childrenField ='children',
  mode = 'DFS'
) {
  const resArr = []
  treeForEach(
    tree,
    (item) => {
      resArr.push(item)
    },
    childrenField,
    mode
  )
  return resArr
}
